import java.util.*;


public class Tablero {
	// Tablero conformado por un arreglo de numeroDeEspacios caracteres
	// Espacio es vacio, X para el jugador 1 y O para el jugador 2
	private char[] tablero;
        private int numeroDeColumnas = 5;
        public int numeroDeEspacios = numeroDeColumnas * numeroDeColumnas;
        public int ganador;
	
	// Constructor
	Tablero(){
		tablero = new char[numeroDeEspacios];
		for (int i = 0; i < numeroDeEspacios; i++){
			tablero[i] = ' ';
		}
		ganador = 0;
	}     
	
	// Jugada del jugador 1
	public void marcarJugador1(int ind){
		if(tablero[ind] == ' '){
			tablero[ind] = 'X';
		}
	}
	
	// Jugada del jugador 2
	public void marcarJugador2(int ind){
		if(tablero[ind] == ' '){
			tablero[ind] = 'O';
		}		
	}
	
	// Limpia un indice del tablero
	public void limpiarIndice(int ind){
		tablero[ind] = ' ';
	}
	
	// Devuelve un indice del tablero
	public char getIndice(int ind){
		return tablero[ind];
	}
	
	public void marcarIndice(int ind, char val){
		tablero[ind] = val;
	}
	
	public int getGanador(){
		return ganador;
	}
        
        //Itero sobre las lineas del tablero para obtener los 6 atributos del tablero.
        //Cantidad de 3X: x3 : atributos[0] //3 en linea se gano el partido
        //Cantidad de 3o: 03 : atributos[1]     
        //Cantidad de 2X: x2 : atributos[2] //hay posibilidad de ganar
        //Cantidad de 2o: o2 : atributos[3]   
        //Cantidad de 1X: x1 : atributos[4] 
        //Cantidad de 1o: o1 : atributos[5]
        public int [] getAtributos( char[][] lineas) {
            int atributos[] = new int[] {0,0,0,0,0,0}; //Esto son los x3,o3,x2,o2,x1,o1
            for (char[] linea : lineas) {
                int xs = 0;
                int os = 0;
                int zs = 0;
                
                for (char elem : linea) {
                    if (elem == 'X'){
                        xs++;
                    } else if (elem == 'O'){
                        os++;
                    }  
                    else {
                        zs++;
                    }
                }
                
                if (xs == numeroDeColumnas){
                    atributos[0]++; //x3
                }
                else if(os == numeroDeColumnas) {
                    atributos[1]++; //o3
                }
                else if(xs == (numeroDeColumnas-1) && zs==1) { //x2
                    atributos[2]++;
                }
                else if(os == (numeroDeColumnas-1) && zs==1) { //o2
                    atributos[3]++;
                }
                else if( (xs == (numeroDeColumnas-2) && zs==2)|| (xs == (numeroDeColumnas-3) && zs==3) || (xs == (numeroDeColumnas-4) && zs==4) ) { //x1
                    atributos[4]++;
                }
                else if( (os == (numeroDeColumnas-2) && zs==2)|| (os == (numeroDeColumnas-3) && zs==3) || (os == (numeroDeColumnas-4) && zs==4) ) { //x1
                    atributos[5]++;
                }  
                
            }
	    //System.out.println("x3:" + atributos[0] + " o3:" + atributos[1] + " x2:" + atributos[2] + " o2:" + atributos[3] + " x1:" + atributos[4] + " o1:" + atributos[5] +  "\n");

            return atributos;
        
        }
        //Devuelve un array que contiene las columnas, filas y diagonales del tablero
        public char[][] getLineas() {

            int cantidadDeLineas = numeroDeColumnas*2 +2;
            char[][] lineas = new char[cantidadDeLineas][numeroDeColumnas]; // el numero de lineas son 2*numeroDeColumnas de columnas y filas mas 2 diagonales
            int nColumna = 0;
            int nFila=0;
            int nDiagonal = 0;
            
            //obtengo las filas
            for (int i=0 ; i<numeroDeColumnas;i++) {
                for (int j=0; j< numeroDeColumnas;j++) {
                        lineas[i][j] = tablero[nFila+j]; //armo las columnas
                }   
                nFila +=numeroDeColumnas;           

            }
            
            nFila = 0;
                 
            //obtengo las columnas
            for (int i=numeroDeColumnas ; i<numeroDeColumnas*2;i++) {
                for (int j=0; j< numeroDeColumnas; j++) {
                    lineas[i][j] = tablero[nColumna]; //armo las columnas
                    nColumna +=numeroDeColumnas;    
                }  
                nFila++;

                nColumna = nFila;
                
            }      

            for (int i=numeroDeColumnas*2 ; i<cantidadDeLineas-1;i++) {
                for (int j=0; j< numeroDeColumnas; j++) {
                    lineas[i][j] = tablero[nDiagonal]; //armo las columnas
                    nDiagonal +=numeroDeColumnas+1;    
                }   
            }             
            nDiagonal = numeroDeColumnas-1;
            for (int i=numeroDeColumnas*2+1 ; i<cantidadDeLineas;i++) {
                for (int j=0; j< numeroDeColumnas; j++) {
                    lineas[i][j] = tablero[nDiagonal]; //armo las columnas
                    nDiagonal +=numeroDeColumnas-1;    

                }   
            }             

            
            return lineas;
        }
        
        public double evaluarTablero(double[] pesos, int jugador) {
            int atributos[] = this.getAtributos(this.getLineas());
            double valorEstimado = 0;
            
            if (!juegoTerminado()){
                 valorEstimado = pesos[0] + 
                                pesos[1]*atributos[0] +
                                pesos[2]*atributos[1] +
                                pesos[3]*atributos[2] +
                                pesos[4]*atributos[3] +
                                pesos[5]*atributos[4] +
                                pesos[6]*atributos[5];
                
                 if (valorEstimado > 100) {
                     valorEstimado = 99.9;
                 }else if (valorEstimado <-100) {
                     valorEstimado = -99.9;
                 }
            } else {
            	if (ganador == jugador){
            		valorEstimado = 100;
            	} else {
            		if (ganador == 0){
            			valorEstimado = 0;
            		} else {
            			valorEstimado = -100;
            		}
            	}
            }


	    //System.out.println("valor tablero estimado:" + valorEstimado +  "\n");
            
            return valorEstimado;

        }
	
	public void imprimirTablero(){
            int nFila = 0;
            
            System.out.println("\n");
            //obtengo las filas
            for (int i=0 ; i<numeroDeColumnas;i++) {
                for (int j=0; j< numeroDeColumnas;j++) {
                    if( tablero[nFila+j] != ' ') {
                        System.out.print( " " + tablero[nFila+j] + " | " );                
                    } else {
                        //System.out.print(" "+(nFila+j) + " | " );
                        System.out.format("%02d | ", nFila+j);
                    
                    }
                }   
                nFila +=numeroDeColumnas;           
                System.out.println();

                System.out.println("------------------------");

            }
            

	}
	
	// 
	public boolean juegoTerminado(){
		int atributos[] = this.getAtributos(this.getLineas());
		boolean res = false;
		boolean todoMarcado = true;
		for (int i = 0; i < numeroDeEspacios; i++){
			if (tablero[i] == ' '){
				todoMarcado = false;
			}
		}
		
		if ((atributos[0] > 0) || (atributos[1] > 0) || todoMarcado){
			res = true;
            if (atributos[0] > 0) {
                ganador = 1;
            } 
        	if( atributos[1] >0) {
        		ganador = 2;
        	} 
        	if ((atributos[0] == 0) && (atributos[1] == 0)){
        		 ganador = 0;
        	}
            
		}
		return res;
	}
}
